package com.campol.activity;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;

import com.campol.R;
import com.campol.http.ServiceManager;
import com.campol.utils.Constants;
import com.campol.utils.UserPreferences;

public class HomeScreenActivity extends Activity implements OnClickListener, LocationListener {

	private static final int A_MINUTE = 1000 * 60;
	
	private ProgressDialog pdBar;
	
	private LocationManager mlManager;
	
	private boolean cameraReport, policeReport;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		pdBar = new ProgressDialog(this);
		pdBar.setIndeterminate(true);
		pdBar.setTitle("Loading");
		pdBar.setMessage("Posting report...");
		
		findViewById(R.id.main_camera).setOnClickListener(this);
		findViewById(R.id.main_police).setOnClickListener(this);
		mlManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
	}

	@Override
	public void onClick(View v) {
		mlManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
		if (pdBar != null) {
			pdBar.setMessage("Updating location...");
			pdBar.show();
		}
		switch (v.getId()) {
		case R.id.main_camera:
			cameraReport = true;
			policeReport = false;
			break;
		case R.id.main_police:
			cameraReport = false;
			policeReport = true;
			break;
		}
	}

	@Override
	public void onLocationChanged(Location location) {
		new PostWarningTask().execute(location);
	}

	@Override
	public void onProviderDisabled(String provider) {
	}

	@Override
	public void onProviderEnabled(String provider) {
	}

	@Override
	public void onStatusChanged(String provider, int status, Bundle extras) {
	}

	private class PostWarningTask extends AsyncTask<Location, Void, Boolean> {
		
		@Override
		protected void onPreExecute() {
			if (pdBar != null && pdBar.isShowing()) {
				pdBar.setMessage("Posting report...");
			} else if (pdBar != null) {
				pdBar.show();
			}
		}

		@Override
		protected Boolean doInBackground(Location... params) {
			Location location = params[0];
			if (location != null){
				String reportUrl = Constants.API_ADD_AMBUSH;
				String token = UserPreferences.getUserToken(HomeScreenActivity.this);
				if (cameraReport) {
					reportUrl = String.format(reportUrl, token, location.getLatitude(), location.getLongitude(), Constants.AMBUSH_TYPE_CAMERA);
				} else if (policeReport) {
					reportUrl = String.format(reportUrl, token, location.getLatitude(), location.getLongitude(), Constants.AMBUSH_TYPE_POLICE);
				}
				//and stop progress bar and unregister location listener 
				mlManager.removeUpdates(HomeScreenActivity.this);
				return ServiceManager.postRequestOfWarning(reportUrl);
			}
			return null;
		}
		
		@Override
		protected void onPostExecute(Boolean result) {
			if (pdBar != null && pdBar.isShowing()) {
				pdBar.dismiss();
			}
			if (result == null || result==false) {
				//TODO: say about failed operation
				Toast.makeText(HomeScreenActivity.this, "Report failed. The spot was not added", Toast.LENGTH_SHORT).show();
				return;
			}
			//TODO: say about success
			Toast.makeText(HomeScreenActivity.this, "Successful report. The spot was added.", Toast.LENGTH_SHORT).show();
		}
	}

	/** Determines whether one Location reading is better than the current Location fix
	  * @param location  The new Location that you want to evaluate
	  * @param currentBestLocation  The current Location fix, to which you want to compare the new one
	  */
	protected boolean isBetterLocation(Location location, Location currentBestLocation) {
	    if (currentBestLocation == null) {
	        // A new location is always better than no location
	        return true;
	    }

	    // Check whether the new location fix is newer or older
	    long timeDelta = location.getTime() - currentBestLocation.getTime();
	    boolean isSignificantlyNewer = timeDelta > A_MINUTE;
	    boolean isSignificantlyOlder = timeDelta < -A_MINUTE;
	    boolean isNewer = timeDelta > 0;

	    // If it's been more than two minutes since the current location, use the new location
	    // because the user has likely moved
	    if (isSignificantlyNewer) {
	        return true;
	    // If the new location is more than two minutes older, it must be worse
	    } else if (isSignificantlyOlder) {
	        return false;
	    }

	    // Check whether the new location fix is more or less accurate
	    int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
	    boolean isLessAccurate = accuracyDelta > 0;
	    boolean isMoreAccurate = accuracyDelta < 0;
	    boolean isSignificantlyLessAccurate = accuracyDelta > 200;

	    // Check if the old and new location are from the same provider
	    boolean isFromSameProvider = isSameProvider(location.getProvider(),
	            currentBestLocation.getProvider());

	    // Determine location quality using a combination of timeliness and accuracy
	    if (isMoreAccurate) {
	        return true;
	    } else if (isNewer && !isLessAccurate) {
	        return true;
	    } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
	        return true;
	    }
	    return false;
	}

	/** Checks whether two providers are the same */
	private boolean isSameProvider(String provider1, String provider2) {
	    if (provider1 == null) {
	      return provider2 == null;
	    }
	    return provider1.equals(provider2);
	}
	
}
